home *** CD-ROM | disk | FTP | other *** search
- {
- From: RANDALL WOODMAN
- Subj: CMOS Info
-
- Does anyone know how to get the hard drive type(s) from CMOS ?
- }
-
- USES DOS,CRT;
-
- TYPE
- String80 = STRING [80]; { some general purpose string types }
- String40 = STRING [40];
- String30 = STRING [30];
- String20 = STRING [20];
- String12 = STRING [12];
- String10 = STRING [10];
- String5 = STRING [5];
-
- CMOSRec = RECORD
- Found : BOOLEAN; { was a CMOS found to exist }
- CmosDate : String30; { the date found in CMOS }
- CmosTime : String30; { the time found in CMOS }
- VideoType : String10; { Type of video found in CMOS }
- Coproc : BOOLEAN; { does CMOS report a math coprocessor }
- FloppyA : String12; { type of floppy drive for A }
- FloppyB : String12; { Type of floppy drive for B }
- Hard0 : BYTE; { Type of hard drive for drive 0 }
- Hard1 : BYTE; { Type of hard drive for Drive 1 }
- ConvenRam : WORD; { amount of conventional ram indicated }
- ExtendRam : WORD; { amount of extended Ram indicated }
- checkSum : BOOLEAN; { Did checksum pass }
- END; { CMOS Rec }
-
- CONST
- { values of constants for CMOS }
- DayName : ARRAY [0..7] OF STRING [9] = ('Sunday', 'Monday', 'Tuesday',
- 'Wednesday', 'Thursday', 'Friday',
- 'Saturday', 'Sunday');
- MonthName : ARRAY [0..12] OF STRING [9] = ('???', 'January', 'February', 'March',
- 'April', 'May', 'June', 'July',
- 'August', 'September', 'October',
- 'November', 'December');
- ScreenName : ARRAY [0..3] OF STRING [10] = ('EGA/VGA', 'CGA 40col',
- 'CGA 80col', 'Monochrome');
- FloppyName : ARRAY [0..5] OF STRING [11] = ('none', '5.25" 360K',
- '5.25" 1.2M', '3.5" 720K',
- '3.5" 1.44M', '3.5" 2.88M');
- CMOSport : BYTE = $70; { port to access the CMOS }
-
- Country : BYTE = 0; { used for country date format }
-
- {===========================================================================}
-
-
- VAR
- Regs : REGISTERS; { General purpose variable to access
- registers }
- CMOS : CMOSRec; { variable to hold CMOS data }
-
- FUNCTION nocarry : BOOLEAN;
- { returns the status of the carry flag }
- BEGIN
- nocarry := regs.flags AND fcarry = $0000
- END; {nocarry}
-
- {---------------------------------------------------------------------------}
-
- FUNCTION ByteToWord (ByteA, ByteB : BYTE) : WORD;
- BEGIN
- ByteToWord := WORD (ByteB) SHL 8 + ByteA
- END; {cbw}
-
- {---------------------------------------------------------------------------}
-
- FUNCTION BitIsSet (CheckWord : WORD; AndValue : WORD) : BOOLEAN;
- { returns true if the bit(s) indicated in AndValue are set in CheckByte }
- BEGIN
- BitIsSet := CheckWord AND AndValue = AndValue;
- END;
-
- {---------------------------------------------------------------------------}
-
- FUNCTION ReadCMOS (ADDR : BYTE) : BYTE;
- { read a value from the CMOS }
- BEGIN
- IF CMOSport = $70 THEN
- BEGIN
- INLINE ($FA);
- Port [CMOSport] := ADDR;
- readCMOS := Port [CMOSport + 1];
- INLINE ($FB)
- END
- END; {readCMOS}
-
- {---------------------------------------------------------------------------}
-
- FUNCTION addzero (b : BYTE) : string5;
- VAR
- c2 : STRING [2];
- BEGIN
- STR (b : 0, c2);
- IF b < 10 THEN
- c2 := '0' + c2;
- addzero := c2
- END; {addzero}
-
- {---------------------------------------------------------------------------}
-
- FUNCTION ChangeBCD (b : BYTE) : BYTE;
- { change a BCD into a byte structure }
- BEGIN
- ChangeBCD := (b AND $0F) + ( (b SHR 4) * 10)
- END; {ChangeBCD}
-
- {---------------------------------------------------------------------------}
-
- FUNCTION Long2Str (Long : LONGINT) : STRING;
- VAR Stg : STRING;
- BEGIN
- STR (Long, Stg);
- Long2Str := Stg;
- END;
-
- FUNCTION HexL (argument : LONGINT) : STRING; Assembler;
- asm
- cld
- les di, @result
- mov al, 8 { store string length }
- stosb
- mov cl, 4 { shift count }
-
- mov dx, WORD PTR Argument + 2 { hi word }
- call @1 { convert dh to ascii }
- mov dh, dl { lo byte of hi word }
- call @1 { convert dh to ascii }
- mov dx, WORD PTR Argument { lo word }
- call @1 { convert dh to ascii }
- mov dh, dl { lo byte of lo word }
- call @1 { convert dh to ascii }
- jmp @2
-
- @1 :
- mov al, dh { 1 byte }
- AND al, 0fh { low nybble }
- add al, 90h
- daa
- adc al, 40h
- daa
- mov ah, al { store }
- mov al, dh { 1 byte }
- SHR al, cl { get high nybble }
- add al, 90h
- daa
- adc al, 40h
- daa
- stosw { move characters to result }
- retn { return near }
- @2 :
- END;
-
- FUNCTION GetCMOSDate : String30;
- { gets the date found in the CMOS and returns it in string format }
- VAR
- Date,
- Century,
- Year,
- Month : BYTE;
- WorkStr : String30;
- BEGIN
- WorkStr := '';
- date := ChangeBCD (readCMOS (7) );
- century := ChangeBCD (readCMOS ($32) );
- year := ChangeBCD (readCMOS (9) );
- month := ChangeBCD (readCMOS (8) );
- CASE country OF
- 0, 3..255 :
- WorkStr := WorkStr + Monthname [month] + ' ' + Long2Str (date) + ', ' + Long2Str (century) + addzero (year);
- 1 :
- WorkStr := WorkStr + Long2Str (date) + ', ' + Monthname [month] + ' ' + Long2Str (century) + addzero (Year);
- 2 :
- WorkStr := WorkStr + Long2Str (century) + addzero (Year) + ', ' + Monthname [month] + ' ' + Long2Str (date);
- END; {case}
- GetCMosDate := workStr;
- END; { GetCMOSDate }
-
- {---------------------------------------------------------------------------}
-
- FUNCTION GetCmosTime : String30;
- { returns the time as found in the CMOS }
- VAR
- CH : CHAR;
- Hour,
- Min,
- Sec : BYTE;
- WorkStr : String30;
- IsPM : BOOLEAN;
- BEGIN
- workStr := '';
- hour := ChangeBCD (readCMOS (4) );
- min := ChangeBCD (readCMOS (2) );
- sec := ChangeBCD (readCMOS (0) );
- IsPm := FALSE;
- CASE hour OF
- 0 : hour := 12;
- 1..11 : hour := hour;
- 12 : IsPM := TRUE;
- 13..23 : BEGIN
- IsPM := TRUE;
- hour := hour - 12
- END;
- END; {case}
- WorkStr := WorkStr + AddZero (hour) + ':' + addzero (min) + ':' + addzero (sec);
- IF IsPM THEN
- workStr := WorkStr + ' PM'
- ELSE
- WorkStr := WorkStr + ' AM';
- GetCMOSTime := WorkStr;
- END; { GetCmosTime }
-
- {---------------------------------------------------------------------------}
-
- FUNCTION GetCmosCheckSum : BOOLEAN;
- { performs checksum on CMOS and returns true if ok }
- VAR
- CheckSum1,
- CheckSum2 : WORD;
- Count : BYTE;
- BEGIN
- checksum1 := 0;
- FOR count := $10 TO $2D DO
- INC (checksum1, readCMOS (count) );
- checksum2 := (WORD (256) * readCMOS ($2E) ) + readCMOS ($2F);
- IF checksum1 = checksum2 THEN
- GetCmosCheckSum := TRUE
- ELSE
- GetCmosCheckSum := FALSE;
- END; { GetCmosCheckSum }
-
- {---------------------------------------------------------------------------}
-
- PROCEDURE GetCMos;
- { gets the cmos record if it exist }
- VAR
- Floppy : BYTE;
- BEGIN
- FILLCHAR (CMOS, SIZEOF (CMos), 0);
- regs.AH := $C0;
- INTR ($15, regs);
- IF nocarry OR (Mem [$F000 : $FFFE] <= $FC) THEN
- WITH CMOS DO
- BEGIN
- Found := TRUE;
- CMOSDate := GetCMOSDate;
- CMOSTime := GetCmosTime;
- VideoType := ScreenName [ (readCMOS ($14) SHR 4) AND 3];
- CoProc := BitIsSet (readCMOS ($14), 1);
- Floppy := readCMOS ($10);
- IF (Floppy SHR 4) < 5 THEN
- FloppyA := FloppyName [floppy SHR 4]
- ELSE
- FloppyA := 'Unknown ' + HexL (floppy SHR 4);
- IF (floppy AND $0F) < 5 THEN
- FloppyB := FloppyName [floppy AND $0F]
- ELSE
- FloppyB := 'Unknown ' + HexL (floppy AND $0F);
-
- Hard0 := readCMOS ($12);
- Hard0 := Hard0 SHR 4;
- Hard1 := ReadCmos ($12);
- Hard1 := Hard1 AND $0F;
- IF Hard0 = $F THEN
- Hard0 := readCMOS ($19)
- ELSE Hard0 := $FF; { error }
- IF Hard1 = $F THEN
- Hard1 := readCMOS ($1A)
- ELSE Hard1 := $FF;
- ConvenRam := WORD (256) * readCMOS ($16) + readCMOS ($15); { value in K }
- ExtendRam := WORD (256) * readCMOS ($18) + readCMOS ($17); { value in K }
- CheckSum := GetCmosCheckSum;
- END
- ELSE
- CMOS.Found := FALSE;
- END;
-
- BEGIN
- ClrScr;
- GetCMos;
- With CMOS DO
- BEGIN
- WriteLn('Date : ',CMosDate);
- WriteLn('Time : ',CMosTime);
- WriteLn('Video : ',VideoType);
- WriteLn('Math : ',CoProc);
- WriteLn('FloppyA : ',FloppyA);
- WriteLn('FloppyB : ',FloppyB);
- WriteLn('Hard #1 : ',Hard0);
- WriteLn('Hard #2 : ',Hard1);
- WriteLn('Base Ram : ',ConvenRam,'K');
- WriteLn('Ext Ram : ',ExtendRam,'K');
- ReadKey;
- END;
- END.